// demo-send.cpp : Defines the entry point for the console application.
//

#include<gst/gst.h>
#define RECV_IP "192.168.1.6"

static gboolean
bus_call( GstBus *bus,GstMessage *msg, gpointer data )
{
	GMainLoop *loop = ( GMainLoop* )data;
	switch( GST_MESSAGE_TYPE( msg )) {
		case GST_MESSAGE_EOS:
					g_print ( "End-of-stream\n" );
					g_main_loop_quit( loop );
					break;
		case GST_MESSAGE_ERROR: {
					gchar *debug;
					GError* err;
					gst_message_parse_error( msg,&err,&debug );
					g_print ( "Error: %s\n", err ->message );
					g_error_free( err );
					g_main_loop_quit ( loop );
					break;
		}
		default:
					break;
	}
	return TRUE;
}

int main(int argc, char*  argv[])
{
	GstElement *pipeline;
	GstElement *source,*queue,*videoscale,*capsfilter;
	GstElement *ffmpegcs, *encoder, *rtph264pay;
	GstElement *rtpbin, *udpsink_rtp, *udpsink_rtcp,*udpsrc_rtcp;
	GstElement *sink, *tee, *queuesave,*queuesend;
	GstElement *filesink;
	GstElement *decoder, *ffmpegcsd;
	GMainLoop  *loop;
	GstCaps* caps;
	gboolean ret =  FALSE;

	gst_init ( NULL, NULL );
	loop = g_main_loop_new( NULL,FALSE );
	caps = gst_caps_from_string( "video/x-raw-yuv,width=320,height=240" );// GST_STATIC_CAPS( "video/x-raw-yuv,width=320,height=240" );
	
	pipeline      = gst_pipeline_new( "video-send" );
	source        = gst_element_factory_make ( "v4l2src","file-source" );
	queue         = gst_element_factory_make ( "queue", "queue" );
	videoscale    = gst_element_factory_make ( "videoscale", "videoscale" );
	capsfilter    = gst_element_factory_make ( "capsfilter", "capsfilter" );
	ffmpegcs      = gst_element_factory_make ( "ffmpegcolorspace", "ffmpegcs" );
	ffmpegcsd     = gst_element_factory_make ( "ffmpegcolorspace", "ffmpegcsd" );     
	encoder       = gst_element_factory_make ( "x264enc", "encoder" );
	rtph264pay    = gst_element_factory_make ( "rtph264pay", "rtph264pay" );
	rtpbin		  = gst_element_factory_make ( "gstrtpbin", "rtpbin" );
	udpsink_rtp   = gst_element_factory_make ( "udpsink", "udpsink-send data" );
	udpsink_rtcp  = gst_element_factory_make ( "udpsink", "udpsink-rtcp" );
	udpsrc_rtcp	  = gst_element_factory_make ( "udpsrc", "udpsrc-rtcp" );
	sink          = gst_element_factory_make ( "autovideosink", "sink" );//autovideosink
	filesink      = gst_element_factory_make ( "filesink", "filesink" );
	tee           = gst_element_factory_make ( "tee", "tee" );
	queuesave     = gst_element_factory_make ( "queue", "queuesave" );
	queuesend     = gst_element_factory_make ( "queue", "queuesend" );
	decoder       = gst_element_factory_make ( "ffdec_h264", "decoder" );

	if( !pipeline || !source  || !queue || !videoscale || !capsfilter ||
		!ffmpegcs || !encoder || !rtph264pay || !rtpbin || !decoder ||
		!udpsink_rtp || !udpsink_rtcp || !udpsrc_rtcp || 
		!sink || !queuesend || !queuesave ) {
		g_print ( "One element could not be created \n" );
		return -1;
	}

	g_object_set( G_OBJECT ( filesink ), "location", "testsend.txt", NULL );
	g_object_set( G_OBJECT ( capsfilter ),  "caps",  caps, NULL );
	g_object_set( G_OBJECT ( encoder ), "bitrate", 100000, NULL);
	
	g_object_set( G_OBJECT ( udpsink_rtp ), "host", RECV_IP, NULL );
	g_object_set( G_OBJECT ( udpsink_rtp ), "port", 10000, NULL );
	g_object_set( G_OBJECT ( udpsink_rtp ), "async", FALSE, "sync", FALSE, NULL );
	g_object_set( G_OBJECT ( udpsink_rtcp ), "host",RECV_IP, NULL );
	g_object_set( G_OBJECT ( udpsink_rtcp ), "port", 10001, NULL );
	g_object_set( G_OBJECT ( udpsink_rtcp ), "async", FALSE, "sync", FALSE, NULL );
	g_object_set( G_OBJECT ( udpsrc_rtcp ), "port", 10002, NULL );

	//gst_bus_add_watch( gst_pipeline_get_bus( GST_PIPELINE( pipeline ) ),
			//bus_call,loop );
	gst_bin_add_many( GST_BIN( pipeline ), source,ffmpegcs, capsfilter, queue, 
		encoder, tee, queuesave,  decoder, ffmpegcsd, sink,  NULL);
	ret = gst_element_link_many( source, ffmpegcs, capsfilter, queue, tee, NULL );
	ret = gst_element_link_many( tee,  queuesave, /*decoder,*/ffmpegcsd, sink, NULL );

#if 1
	gst_bin_add_many( GST_BIN( pipeline ), queuesend,rtph264pay, 
			rtpbin,udpsink_rtp, udpsink_rtcp, udpsrc_rtcp, NULL );
	ret = gst_element_link_many( tee,  queuesend, encoder, rtph264pay, NULL );
	ret = gst_element_link_pads_filtered( rtph264pay, "src", rtpbin, "send_rtp_sink_0", NULL );
	ret = gst_element_link_pads_filtered( rtpbin, "send_rtp_src_0", udpsink_rtp, "sink", NULL );
	ret = gst_element_link_pads_filtered( rtpbin, "send_rtcp_src_0", udpsink_rtcp,"sink", NULL );
	ret = gst_element_link_pads_filtered( udpsrc_rtcp, "src", rtpbin, "recv_rtcp_sink_0", NULL );
#endif 

	g_print ( "Setting to sending data\n" );
	gst_element_set_state ( pipeline, GST_STATE_PLAYING );
	gst_element_set_locked_state( udpsink_rtcp, TRUE );


	g_main_loop_run( loop );

	

	g_print ( "returned ,stopping playback\n" );
	gst_element_set_state( pipeline, GST_STATE_NULL );

	g_print ( "Deleting pipeline\n" );
	gst_object_unref( GST_OBJECT ( pipeline ) );

	return 0;
}

